/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package TextManager;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;

/**
 *
 * @author Jaime
 */
public class WordOccurrencesMap implements WordOccurrenceHolder {

    private HashMap<WordOccurrence, Word> wordsHash;
    private List<Word> wordsList;
    private int numberWordOccurrences;
    private int numberWords;
    private static final int INITIAL_SIZE = 15000;
    private Vocabulary vocabulary;

    public WordOccurrencesMap(Vocabulary vocabulary) {
        wordsHash = new HashMap<WordOccurrence, Word>();
        wordsList = new ArrayList<Word>(INITIAL_SIZE);
        numberWordOccurrences = 0;
        numberWords = 0;
        this.vocabulary = vocabulary;
    }

    @Override
    public void newOccurrence(WordOccurrence occurrence) {
        Word theWord = wordsHash.get(occurrence);
        if (theWord == null) {
            theWord = new Word(occurrence);
            wordsHash.put(occurrence, theWord);
            wordsList.add(theWord);
            numberWords++;
            vocabulary.newOccurrence(occurrence);
        } else {
            theWord.newOccurrence(occurrence);
        }
        numberWordOccurrences++;
    }

    public void addManyOccurrences(WordOccurrence word, int occurrences) {
        Word theWord = wordsHash.get(word);
        if (theWord == null) {
            theWord = new Word(word);
            wordsHash.put(word, theWord);
            wordsList.add(theWord);
            numberWords++;
            vocabulary.newOccurrence(word);
            theWord.manyNewOccurrences(occurrences - 1);
        } else {
            theWord.manyNewOccurrences(occurrences);
        }
        numberWordOccurrences += occurrences;
    }

    public int getNumberofOccurrences(WordOccurrence word) {
        Word w = wordsHash.get(word);

        return w == null ? 0 : w.getOccurrences();

    }

    public int size() {
        return wordsList.size();
    }

    public String toString() {
        String toString = "";

        toString += "Number of Words = " + numberWords + "\n";
        toString += "Number of Words occurrences = " + getNumberWordOccurrences() + "\n\n";
        toString += "Words:\n";

        //Collections.sort(wordsList);

        Collection<Word> theWords = wordsList;//wordsHash.values();

        for (Word w : theWords) {
            toString += w.toString() + "\n";
        }

        return toString;
    }

    /**
     * @return the numberWordOccurrences
     */
    public int getNumberWordOccurrences() {
        return numberWordOccurrences;
    }

    private class Word implements Comparable {

        private WordOccurrence word;
        private int occurrences;

        public Word(WordOccurrence word) {
            this.word = word;
            occurrences = 1;
        }

        public WordOccurrence getWord() {
            return word;
        }

        public boolean newOccurrence(WordOccurrence word) {
            if (this.word.equals(word)) {
                newOccurrence();
                return true;
            }
            return false;
        }

        public void newOccurrence() {
            occurrences++;
        }

        public void manyNewOccurrences(int occurrences) {
            this.occurrences += occurrences;
        }

        public String toString() {
            return word.toString() + ":" + getOccurrences();
        }

        @Override
        public int compareTo(Object o) {
            Word other = (Word) o;

            //return this.word.getContent().compareTo(other.word.getContent());

            if (other.getOccurrences() == getOccurrences()) {
                return 0;
            } else if (getOccurrences() > other.getOccurrences()) {
                return 1;
            } else {
                return -1;
            }

        }

        /**
         * @return the occurrences
         */
        public int getOccurrences() {
            return occurrences;
        }
    }
}
